import {MailModel, MailState, PublicMailModel, PublicMailRecordModel} from '../../../database/models/mail'
import {PlayerModel} from '../../../database/models/player'

export const typeDefs = `
  type Gift {
    coin: Int
    freeCoin: Int
    gem: Int
    point: Int
  }

  type Mail{
    _id: String
    title: String!
    content: String!
    to: Player!
    createAt: String!
    type: String!
    state: String!
    gift:Gift
    giftState: String
  }

  type PublicMail{
    _id: String!
    title: String!
    content: String!
    type: String!
    gift: Gift
    createAt: String!
  }
`

export const queryDefs = `
  getMailsByShortId(shortId:String!): [Mail]!
  getPublicMails : [PublicMail]!
`

export const mutationDefs = `
  sendMessageMailTo(
    to: String!,
    title: String!,
    content: String!,
    type: String!,
    coin: Int,
    freeCoin: Int,
    gem: Int
    point: Int
  ): Mail
  deleteMail(_id:String!): Boolean,
  sendPublicMail(
    title: String!,
    content: String!
    type: String!,
    coin: Int,
    freeCoin: Int,
    gem: Int,
    point: Int
  ): PublicMail
  deletePublicMail(_id: String!): Boolean
`

export const resolvers = {
  Query: {
    async getMailsByShortId(_, {shortId}, context) {

      const p = await PlayerModel.findOne({shortId}).select({_id: 1}).lean().exec()
      if (p) {
        return MailModel.find({to: p._id})
          .sort({createAt: -1})
          .populate('to')
          .lean().exec()
      } else {
        return []
      }
    },
    getPublicMails: async () => {
      return await PublicMailModel.find().lean()
    }
  },

  Mutation: {
    async sendMessageMailTo(_, {to, title, content, type, coin, freeCoin, gem, point}) {

      const toPlayerModel = await PlayerModel.findOne({shortId: to}).lean().exec()

      if (!toPlayerModel) {
        throw Error('NO_SUCH_PLAYER')
      }

      const mail = new MailModel({
        to: toPlayerModel._id,
        title,
        content,
        type,
        state: MailState.UNREAD,
        createAt: new Date(),
        gift: {coin, freeCoin, gem, point}
      })
      await mail.save()

      const json = mail.toJSON()
      json.to = toPlayerModel

      return json
    },

    async sendPublicMail(_, {title, content, type, coin, freeCoin, gem, point}) {
      const pm = new PublicMailModel({
        title, content, type, createAt: new Date(),
        gift: {coin, freeCoin, gem, point}
      })
      await pm.save()
      return pm
    },
    async deleteMail(_, {_id}) {
      try {
        await MailModel.remove({_id})
        return true
      } catch (e) {
        return false
      }
    },
    async deletePublicMail(_, {_id}) {
      await PublicMailModel.remove({_id})
      await PublicMailRecordModel.remove({mail: _id})
      return true
    }
  }
}
